﻿//TakeProfitStrategy.cs
//Copyright (c) 2013 StockSharp LLC, all rights reserved.
//This code module is part of StockSharp library.
//This code is licensed under the GNU GENERAL PUBLIC LICENSE Version 3.
//See the file License.txt for the license details.
//More info on: http://stocksharp.com

namespace StockSharp.Algo.Strategies
{
	using StockSharp.BusinessEntities;

	/// <summary>
	/// Стратегия защиты прибыли.
	/// </summary>
	public class TakeProfitStrategy : ProtectiveStrategy
	{
		private decimal? _prevPrice;
		private decimal? _trailingActivationPrice;
		private bool _isTrailingActivated;

		/// <summary>
		/// Создать стратегию <see cref="TakeProfitStrategy"/>.
		/// </summary>
		/// <param name="trade">Защищаемая позиция.</param>
		/// <param name="protectiveLevel">
		/// Защитный уровень. Если тип <see cref="Unit.Type"/> равен <see cref="UnitTypes.Limit"/>,
		/// то задается конкретная цена. Иначе, указывается величина сдвига от защищаемой сделки <paramref name="trade"/>.
		/// </param>
		public TakeProfitStrategy(MyTrade trade, Unit protectiveLevel)
			: base(trade, protectiveLevel)
		{
		}

		/// <summary>
		/// Абсолютное значение цены, при достижении которой автивизируется защитная стратегия. Если цена равна 0, то активация не требуется.
		/// </summary>
		public override decimal ActivationPrice
		{
			get
			{
				var isBuy = ProtectiveDirection == OrderDirections.Buy;

				if (_prevPrice == null)
					_prevPrice = BasePrice;

				var bestPrice = BestPrice;

				if (IsTimeOut && (isBuy ? BestPrice > BasePrice : BestPrice < BasePrice))
					return ClosePositionPrice;

				if (IsTrailing)
				{
					if (_trailingActivationPrice == null)
						_trailingActivationPrice = (decimal)(isBuy ? BasePrice + ProtectiveLevel : BasePrice - ProtectiveLevel);

					if (isBuy)
					{
						if (_trailingActivationPrice < bestPrice)
							_isTrailingActivated = true; // активация трейлинга

						if (_isTrailingActivated)
						{
							if (_prevPrice < bestPrice)
							{
								_prevPrice = bestPrice;
							}
							else if (_prevPrice > bestPrice)
							{
								// если при прохождении бызубытка, цена начала откатываться, то нужно быстро закрыть позицию
								return ClosePositionPrice;
							}
						}
					}
					else
					{
						if (_trailingActivationPrice > bestPrice)
							_isTrailingActivated = true; // активация трейлинга

						if (_isTrailingActivated)
						{
							if (_prevPrice > bestPrice)
							{
								_prevPrice = bestPrice;
							}
							else if (_prevPrice < bestPrice)
							{
								// если при прохождении бызубытка, цена начала откатываться, то нужно быстро закрыть позицию
								return ClosePositionPrice;
							}
						}
					}

					return 0;
				}
				else
				{
					var activationPrice = (decimal)(isBuy ? (decimal)_prevPrice + ProtectiveLevel : (decimal)_prevPrice - ProtectiveLevel);

					if (isBuy)
					{
						if (bestPrice >= activationPrice)
							return activationPrice;
					}
					else
					{
						if (bestPrice <= activationPrice)
							return activationPrice;
					}

					return 0;
				}
			}
		}
	}
}